package org.duang.proxy;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.duang.aop.Proxy;
import org.duang.aop.ProxyChain;
import org.duang.common.dto.DRLDto;
import org.duang.common.exceptios.ServiceException;
import org.duang.config.InstanceFactory;
import org.duang.kit.ToolsKit;


/**
 * 框架默认代理类
 * 主要用于日志链路跟踪，记录所有调用该Service Method时的各项记录
 * @author laotang
 */
public class DuangProxy implements Proxy {
	
	public static Map<String, DRLDto> drlDtoMap = Collections.synchronizedMap(new HashMap<String, DRLDto>());
	public static boolean isException = false;
	
//	//	 定义一个请求线程安全线程类
//	private static DuangThreadLocal<LinkedHashMap<String, Map<String,String>>> drlThreadLocal = new DuangThreadLocal<LinkedHashMap<String,Map<String,String>>>() {
//		public LinkedHashMap<String, Map<String,String>> initialValue() {
//			return new LinkedHashMap<String, Map<String,String>>();
//		}
//	};
//	public static void setRequestLink2Map(LinkedHashMap<String, Map<String,String>>map) {
//		drlThreadLocal.set(map);
//	}
//	
//	public static LinkedHashMap<String, Map<String,String>> getRequestLink4Map() {
//		return drlThreadLocal.get();
//	}
//	
//	public static void requestLinkRemove() {
//		drlThreadLocal.remove();
//	}
	
 	@Override
	public Object doProxy(ProxyChain proxyChain) throws Exception { 		
 		Object resultObj = null;
 		Class<?> cls = proxyChain.getTargetClass();
 		Method method = proxyChain.getTargetMethod();
		Object[] params = proxyChain.getMethodParams();
		String uri = cls.getName()+"."+method.getName()+"_"+System.currentTimeMillis();
//		boolean isException = false;
		before(uri);
		try{
			resultObj = proxyChain.doProxyChain();
		} catch (Exception ex) {
//			ex.printStackTrace();
			if(!isException){
				resultObj =ToolsKit.builderExceptionStackTrace(ex);	
				isException = true;
			}
			throw new ServiceException(ex);
		} finally {
			after(uri, params, resultObj, isException);
		}
		
//		if(isException) throw new ServiceException().setMessage((String)resultObj);
		return resultObj;
	}
 	
 	public void before(String uri) throws Exception {
// 		日志字段说明：时间 访问IP 回源IP responsetime referer method 访问URL httpcode requestsize responsesize cache命中状态 UA头 文件类型
// 		Map<String, String> map = new HashMap<String,String>();
// 		map.put("path", uri);
// 		InstanceFactory.setMultiRequestThreadMap(currentThreadKey, map);
//		System.out.println("before:"+ uri+" "+ currentThreadKey);
// 		DuangProxy.getRequestLink4Map().put(uri+"_"+System.currentTimeMillis(), map);
// 		System.out.println(DuangProxy.getRequestLink4Map().size()+"             "+uri );
// 		InstanceFactory.getDrlUriList().add(uri+"."+startTime);
 		Map<String, String> map = new HashMap<String,String>();
 		InstanceFactory.getDrlUriMap().put(uri, map);
	}
	
	public void after(String uri, Object[] params, Object result, boolean isException) throws Exception {
		
		String[] key = uri.split("_");
		if(key[0].trim().equals("org.duang.db.mongo.MongoDao.dBCursor2List")) return;		//过滤掉这个方法，会报类型转换异常
		Map<String,String> map = InstanceFactory.getDrlUriMap().get(uri);		
//		System.out.println(System.currentTimeMillis() - Long.parseLong(key[1])+"                     "+uri);
		map.put("usetime", (System.currentTimeMillis() - Long.parseLong(key[1])+""));
		map.put("target", key[0]);
		map.put("isexception", isException+"");
		
//		try{
//			System.out.println(key[0]+"                              "+ToolsKit.toJsonString(params)  +"                     "+(params.length == 0));	
//		} catch(Exception e){
//			System.out.println("@@@: " + key[0]);
//			e.printStackTrace();
//		}
//		map.put("params", ToolsKit.toJsonString(params));
		if((result instanceof Exception && isException) ){
			map.put("result",ToolsKit.getStackTraceAsString((Exception)result)); //ToolsKit.toJsonString(result)
		} 
//		else {
//			map.put("result", ToolsKit.toJsonString(result));
//		}
		InstanceFactory.getDrlUriMap().put(uri, map);
		
		/*
//		List<Map<String, String>> threadListMap = InstanceFactory.getMultiRequestThreadMap(currentThreadKey);
		
//		Map<String, String> map = new HashMap<String,String>();
//		map.put("endTime", System.currentTimeMillis() - startTime+"");
//		map.put("path", uri);
//		map.put("params", ToolsKit.toJsonString(params));
//		map.put("result", (result instanceof String) ? result.toString() : ToolsKit.toJsonString(result));
//		InstanceFactory.setMultiRequestAfterThreadMap(currentThreadKey, map);
//		System.out.println("###: " + ToolsKit.toJsonString(result));
		
//		DuangProxy.getRequestLink4Map().p
//		System.out.println("################: " + ToolsKit.toJsonString(params));
		Map<String, String> map  = DuangProxy.getRequestLink4Map().get(uri);
		map.put("usetime", System.currentTimeMillis() - startTime+"");
		map.put("path", uri);
		try{
		if(ToolsKit.isNotEmpty(params)){
//			for(Object obj : params){
//				if(obj instanceof Integer){
//					System.out.println((int)obj);
//				} else {
//					System.out.println(obj.getClass().getName());
//					System.out.println("##: " + ToolsKit.toJsonString(obj));
//				}
//			}
			map.put("params", ToolsKit.toJsonString(params));
		}
		}catch(Exception e) {
			e.printStackTrace();
		}
		map.put("result", (isException) ? result.toString() : ToolsKit.toJsonString(result));
		map.put("isexception",isException+"");
		DuangProxy.getRequestLink4Map().put(uri, map);
		*/
	}
}
